home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
SECURITY
/
MNGLR140
/
ASMLEX.L
next >
Wrap
Text File
|
1996-05-01
|
8KB
|
245 lines
%{
{* Assembler parsing for Mangler, see MANGLER.L
Copyright (C) 1993 Berend de Boer
This program is free software for noncommercial users; you can
redistribute it and/or modify it under the terms of the license,
stated in de accompanying file LICENSE.TXT.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
license for more details.
See the accompanying READ.ME file for information on contacting the
author.
$Author: Berend_de_Boer $
$Date: 93/04/29 07:52:25 $
$Revision: 1.2 $
Last changes:
93-04-19 Fixed the & identifier override bug
*}
procedure ParseAsm;
%}
NQUOTE [^']
DQUOTE [^'}]
%%
%{
function is_keyword(const id : string) : Boolean;
{**}
const
id_len = 6;
type
Ident = string[id_len];
const
(* table of assembler keywords: *)
no_of_keywords = 192;
keyword : array [1..no_of_keywords] of Ident = (
'AAA', 'AAD', 'AAM', 'AAS', 'ADC', 'ADD', 'AH', 'AL', 'AND', 'AND',
'AX', 'BH', 'BL', 'BOUND', 'BP', 'BX', 'BYTE', 'CALL', 'CBW', 'CH',
'CL', 'CLC', 'CLD', 'CLI', 'CMC', 'CMP', 'CMPS', 'CMPSB', 'CMPSD',
'CMPSW', 'CS', 'CX', 'DAA', 'DAS', 'DEC', 'DH', 'DI', 'DIV', 'DL', 'DS',
'DWORD', 'DX', 'ENTER', 'ES', 'FAR', 'HIGH', 'HLT', 'IDIV', 'IMUL',
'IN', 'INC', 'INS', 'INSB', 'INSD', 'INSW', 'INT', 'INTO', 'IRET', 'JA',
'JAE', 'JB', 'JBE', 'JC', 'JCXZ', 'JE', 'JG', 'JGE', 'JL', 'JLE', 'JMP',
'JNA', 'JNAE', 'JNB', 'JNBE', 'JNC', 'JNE', 'JNG', 'JNGE', 'JNL',
'JNLE', 'JNO', 'JNP', 'JNS', 'JNZ', 'JO', 'JP', 'JPE', 'JPO', 'JS',
'JZ', 'JZ', 'LAHF', 'LAR', 'LDS', 'LEA', 'LEAVE', 'LES', 'LGDT', 'LIDT',
'LLDT', 'LMSW', 'LOCK', 'LODS', 'LODSB', 'LODSW', 'LOOP', 'LOOPE',
'LOOPNE', 'LOOPNZ', 'LOOPZ', 'LOW', 'LSL', 'LTR', 'MOD', 'MOV', 'MOVS',
'MOVSB', 'MOVSW', 'MUL', 'NEAR', 'NEG', 'NOP', 'NOT', 'NOT', 'OFFSET',
'OR', 'OR', 'OUT', 'OUTS', 'OUTSB', 'OUTSW', 'POP', 'POPA', 'POPF',
'PTR', 'PUSH', 'PUSHA', 'PUSHF', 'QWORD', 'RCL', 'RCR', 'REP', 'REPE',
'REPNE', 'REPNZ', 'REPZ', 'RET', 'ROL', 'ROR', 'SAHF', 'SAL', 'SAR',
'SBB', 'SCAS', 'SCASB', 'SCASW', 'SEG', 'SEGDS', 'SEGES', 'SEGSS', 'SGDT', 'SHL', 'SHL', 'SHR',
'SHR', 'SI', 'SIDT', 'SLDT', 'SMSW', 'SP', 'SS', 'ST', 'STC', 'STD',
'STI', 'STOS', 'STOSB', 'STOSW', 'STR', 'SUB', 'TBYTE', 'TEST', 'TYPE',
'VERR', 'VERW', 'WAIT', 'WORD', 'XCHG', 'XLAT', 'XLATB', 'XOR', 'XOR');
var m, n, k : integer;
begin
m := 1; n := no_of_keywords;
while m<=n do begin
k := m+(n-m) div 2;
if id=keyword[k]
then begin
is_keyword := true;
Exit;
end
else if id>keyword[k]
then m := k+1
else n := k-1
end; { of while }
is_keyword := false
end;
var
Stop : Boolean;
%}
[A-Za-z]([a-zA-Z])* begin
yytext := UpStr(yytext);
if is_keyword(yytext)
then return(KEYWORD)
else begin
if yytext = 'END'
then return(_END)
else return(IDENTIFIER);
end;
end;
[a-zA-Z_]([a-zA-Z0-9_])* begin
yytext := UpStr(yytext);
return(IDENTIFIER);
end;
"&" return(AMPERSAND);
[@]+([a-zA-Z0-9_])+ return(_LABEL);
";" return(SEMICOLON);
"." return(DOT);
'({NQUOTE}|'')*' return(CHARACTER_STRING);
[0-9]([0-9-a-fA-F])*[hH] |
[$]([0-9a-fA-F])+ |
[0-9]+ return(NUMBER);
"{$"({DQUOTE})*"}" return(DIRECTIVE);
"(*" begin
Stop := FALSE;
repeat
if (get_char = '*') and (get_char = ')') then
Stop := TRUE;
until Stop;
end;
"{" begin
repeat
until get_char = '}';
end;
[ \t\f] ;
\n begin
if Random(50) = 25 then
WriteProgress;
return(NEWLINE);
end;
. return(OTHER);
%%
(**)
function GiveEncodingFor(s : string) : string;
{* DO NOT MAKE s a const string!!! *}
{* should be equal to function in MANGLER.PAS *}
{ PRE -
POST - contents of yytext is destroyed
}
var
p,d : PScopeCol;
e : string;
Index : integer;
begin
if yylex = DOT
then begin
{* a dot was used to select a different scope *}
p := GetScope(s, Index);
if p = nil
then begin {* an unknown scope was selected *}
e := s + '.';
while (yylex = IDENTIFIER) do begin
e := e + yytext;
if yylex = DOT
then e := e + '.'
else Break;
end;
yyless(0);
end
else begin
PushScope(CurrentScope);
CurrentScope := p^.AtScope(Index);
e := p^.AtHashedName(Index) + '.';
while (yylex = IDENTIFIER) do begin
if CurrentScope = nil
then begin
e := e + yytext;
(* why this source??? if nil you don't know anything it seems
d := GetScope(yytext, Index);
if d <> nil
then e := e + GiveEncodingFor(yytext)
else e := e + yytext;
*)
end
else begin
if CurrentScope^.Search(@yytext, Index)
then e := e + CurrentScope^.AtHashedName(Index)
else e := e + yytext;
end;
if yylex = DOT
then begin
if CurrentScope <> nil then
if CurrentScope^.Count = 0
then CurrentScope := nil
else CurrentScope := CurrentScope^.AtScope(Index);
e := e + '.';
end
else break;
end; { of while }
yyless(0);
CurrentScope := PopScope;
end;
GiveEncodingFor := e;
end
else begin
yyless(0);
p := GetScope(s, Index);
if p = nil
then GiveEncodingFor := s
else GiveEncodingFor := p^.AtHashedName(Index)
end;
end;
begin
write(yyoutput, yytext, ' ');
while yylex <> _END do begin
case yyretval of
IDENTIFIER : begin
write(yyoutput, GiveEncodingFor(yytext));
end;
NEWLINE : writeln(yyoutput, '{}');
AMPERSAND : begin
write(yyoutput, yytext);
yylex;
write(yyoutput, GiveEncodingFor(yytext));
end;
else write(yyoutput, yytext, ' ');
end; { of case }
end; { of while }
writeln(yyoutput);
write(yyoutput, yytext);
if AssemblerSection then begin
Section := PopSection;
CurrentScope := PopScope;
if ObjectImpl then begin
CurrentScope := PopScope;
ObjectImpl := FALSE;
end;
AssemblerSection := FALSE;
end;
end;